package com.xbongbong.paas.service.workflow.trigger.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasCoUserEntity;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.FilterConditionsPoJo;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataFormExplainHelper;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.SymbolHelp;
import com.xbongbong.paas.help.WorkflowHelp;
import com.xbongbong.paas.help.WorkflowTransferHelp;
import com.xbongbong.paas.model.PaasCoUserModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateDTO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateVO;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.CompareUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.parent.field.FieldAnalyseService;
import com.xbongbong.pro.businessrule.pojo.BusinessRuleInfoPojo;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.PackageStatusEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.workflow.TriggerEventTypeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formdata.pojo.vo.BeforeSaveVO;
import com.xbongbong.pro.formdata.pojo.vo.BeforeUpdateVO;
import com.xbongbong.pro.team.TeamAfterVerifyDTO;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.enums.UserTeamEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.help.FormatProductHelp;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.service.toolbox.help.PackageStatusHelp;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.enums.WorkflowNodeTypeEnum;
import com.xbongbong.workflow.model.WorkflowModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowRabbitmqDTO;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.pojo.nodes.FormTriggerNode;
import com.xbongbong.workflow.producer.WorkflowProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author chenpeng
 * @version 1.0
 * @date 2021-05-13 19:32
 * @description
 */
@Service
@Slf4j
public class WorkflowFormDataOperationServiceImpl implements WorkflowFormDataOperationService {

    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private WorkflowHelp workflowHelp;
    @Resource
    private Map<Integer, FieldAnalyseService> fieldAnalyseMap;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private FormDataFormExplainHelper formDataFormExplainHelper;
    @Resource
    private WorkflowProducer workflowProducer;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PackageStatusHelp packageStatusHelp;

    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private PaasCoUserModel paasCoUserModel;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private FormatProductHelp formatProductHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;

    /**
     *
     * @param corpid
     * @param formId
     * @param businessType
     * @return
     */
    @Override
    public List<WorkflowEntity> getSatisfyTriggerEntitys(String corpid, Long formId, Integer businessType, List<Integer> triggerType) throws XbbException {
        Map<String, Object> params = new HashMap<>();
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.FORMID, formId);
        params.put(ParameterConstant.BUSINESS_TYPE, businessType);
        params.put("currentVersion", 1);
        params.put("triggerEventTypeIn", triggerType);
        params.put(ParameterConstant.ENABLE, 1);
        params.put(ParameterConstant.DEL, 0);
        params.put(ParameterConstant.ORDER_BY_STR, "priority asc");
        return workflowModel.findEntitys(params);
    }
    
    /**
     * 工作流add触发
     * @param formDataAddDTO
     * @param beforeSaveVO
     * @param formDataSaveVO
     * @throws XbbException
     */
    @Override
    public void workflowAddTrigger(FormDataAddDTO formDataAddDTO, BeforeSaveVO beforeSaveVO, FormDataAddVO formDataSaveVO) throws XbbException {
        try {
            // TODO: 2021/6/3 并行/串行触发
            List<WorkflowEntity> list = formDataAddDTO.getWorkflowEntityList();

            if (CollectionsUtil.isNotEmpty(list)) {
                WorkflowEntity workflowEntity = list.get(0);
                WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), formDataAddDTO.getCorpid(), "startNode");

                PaasFormDataEntity paasFormDataEntity = beforeSaveVO.getPaasFormDataEntity();
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), formDataAddDTO.getBusinessType())) {
                    WorkOrderEntity workOrderEntity = beforeSaveVO.getWorkOrderEntity();
                    paasFormDataEntity = new PaasFormDataEntity(workOrderEntity.getId(), workOrderEntity.getCorpid(), workOrderEntity.getAppId(), workOrderEntity.getMenuId(), workOrderEntity.getFormId(),
                            workOrderEntity.getSerialNo(), workOrderEntity.getOwnerId(), workOrderEntity.getDepartmentId(), workOrderEntity.getFlowStatus(), workOrderEntity.getData(), workOrderEntity.getCreatorId(),
                            workOrderEntity.getAddTime(), workOrderEntity.getUpdateTime(), workOrderEntity.getDel());
                }
                SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = beforeSaveVO.getSaasNeedRedundantAttrPojo();
                setSaasNeedPojo(saasNeedRedundantAttrPojo);
                //构建mq消息
                WorkflowRabbitmqDTO workflowRabbitmqDTO = buildMqMessage(startNode, formDataAddDTO.getCorpid(), paasFormDataEntity, formDataAddDTO.getLoginUser(), beforeSaveVO.getExplainMap(), saasNeedRedundantAttrPojo, WorkflowOperateEnum.ADD.getType(), formDataAddDTO.getIsImport(), formDataAddDTO.getSubBusinessType());
                workflowRabbitmqDTO.setOpenConversationId(formDataAddDTO.getOpenConversationId());
                workflowRabbitmqDTO.setOperatorId(formDataAddDTO.getUserId());
                //发送mq
                startWorkflow(formDataAddDTO.getIsImport(), workflowRabbitmqDTO);

                // 判断工作流下一个节点是不是审批节点，是，修改同步返回提示
                WorkflowNodeEntity nextNode = workflowHelp.deliverToNextNode(workflowRabbitmqDTO.getWorkflowTransferPOJO(), startNode);
                if (Objects.equals(nextNode.getType(), WorkflowNodeTypeEnum.APPROVE_NODE.getType())) {
                    formDataSaveVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
                    formDataSaveVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                } else if (Objects.equals(nextNode.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())) {
                    WorkflowNodeEntity workflowNodeEntity = workflowHelp.deliverToNextNode(workflowRabbitmqDTO.getWorkflowTransferPOJO(), nextNode);
                    if (!Objects.isNull(workflowNodeEntity) && Objects.equals(workflowNodeEntity.getType(), WorkflowNodeTypeEnum.APPROVE_NODE.getType())) {
                        formDataSaveVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
                        formDataSaveVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                    }
                }

            }

        } catch (Exception e) {
            log.error("新增触发工作流失败", e);
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        
    }
    
    /**
     * 构建mq消息
     * @param startNode
     * @param corpid
     * @param paasFormDataEntity
     * @param loginUser
     * @param saasNeedRedundantAttrPojo
     * @param operate
     * @param subBusinessType
     */
    private WorkflowRabbitmqDTO buildMqMessage(WorkflowNodeEntity startNode, String corpid,
                                               PaasFormDataEntity paasFormDataEntity, UserVO loginUser, Map<String, FieldAttrEntity> explainMap,
                                               SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo, Integer operate, Integer isImport, Integer subBusinessType) throws XbbException{

        WorkflowTransferPOJO workflowTransferPOJO = WorkflowTransferHelp.createTransferData(paasFormDataEntity, explainMap, null, null, corpid, loginUser, startNode, operate, isImport, subBusinessType);
        if (UserTeamEnum.hasTeam(startNode.getBusinessType())) {
            Map<Long, List<String>> mainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), Arrays.asList(paasFormDataEntity.getId()), corpid,
                    startNode.getBusinessType(), false, mainMap, coUserMap, BasicConstant.ZERO);
            //formDataFormExplainHelper.getUserIdMap(Arrays.asList(paasFormDataEntity.getId()), corpid, startNode.getBusinessType(), false, mainMap, coUserMap);
            workflowTransferPOJO.getData().getData().put(FieldTypeEnum.OWNERID.getAlias(), mainMap.get(paasFormDataEntity.getId()) == null ? new ArrayList<>() : mainMap.get(paasFormDataEntity.getId()));
            workflowTransferPOJO.getData().getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserMap.get(paasFormDataEntity.getId()) == null ? new ArrayList<>() : coUserMap.get(paasFormDataEntity.getId()));
            workflowTransferPOJO.getData().getData().put(FieldTypeEnum.CREATORID.getAlias(), paasFormDataEntity.getCreatorId());
        }
        return new WorkflowRabbitmqDTO(workflowTransferPOJO, startNode, saasNeedRedundantAttrPojo);
    }
    
    /**
     * 工作流更新触发
     * @param formDataUpdateDTO
     * @param beforeUpdateVO
     * @throws XbbException
     */
    @Override
    public void workflowUpdateTrigger(FormDataUpdateDTO formDataUpdateDTO, BeforeUpdateVO beforeUpdateVO, FormDataUpdateVO formDataSaveVO) throws XbbException {
        try {
            List<WorkflowEntity> list = formDataUpdateDTO.getWorkflowEntityList();
            if (CollectionsUtil.isNotEmpty(list)) {
                WorkflowEntity workflowEntity = list.get(0);
                WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), formDataUpdateDTO.getCorpid(), "startNode");

                PaasFormDataEntity paasFormDataEntity = beforeUpdateVO.getPaasFormDataEntity();
                SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = beforeUpdateVO.getSaasNeedRedundantAttrPojo();
                setSaasNeedPojo(saasNeedRedundantAttrPojo);

                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), formDataUpdateDTO.getBusinessType())) {
                    WorkOrderEntity workOrderEntity = beforeUpdateVO.getWorkOrderEntity();
                    paasFormDataEntity = new PaasFormDataEntity(workOrderEntity.getId(), workOrderEntity.getCorpid(), workOrderEntity.getAppId(), workOrderEntity.getMenuId(), workOrderEntity.getFormId(),
                            workOrderEntity.getSerialNo(), workOrderEntity.getOwnerId(), workOrderEntity.getDepartmentId(), workOrderEntity.getFlowStatus(), workOrderEntity.getData(), workOrderEntity.getCreatorId(),
                            workOrderEntity.getAddTime(), workOrderEntity.getUpdateTime(), workOrderEntity.getDel());
                }
                WorkflowRabbitmqDTO workflowRabbitmqDTO = buildMqMessage(startNode, formDataUpdateDTO.getCorpid(), paasFormDataEntity, formDataUpdateDTO.getLoginUser(), beforeUpdateVO.getExplainMap(), saasNeedRedundantAttrPojo, WorkflowOperateEnum.UPDATE.getType(), formDataUpdateDTO.getIsImport(), formDataUpdateDTO.getSubBusinessType());
                PaasFormDataEntity oldPaasFormData = beforeUpdateVO.getOldPaasFormData();
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), formDataUpdateDTO.getBusinessType())) {
                    WorkOrderEntity oldWorkOrderEntity = beforeUpdateVO.getOldWorkOrderEntity();
                    oldPaasFormData = new PaasFormDataEntity(oldWorkOrderEntity.getId(), oldWorkOrderEntity.getCorpid(), oldWorkOrderEntity.getAppId(), oldWorkOrderEntity.getMenuId(), oldWorkOrderEntity.getFormId(),
                            oldWorkOrderEntity.getSerialNo(), oldWorkOrderEntity.getOwnerId(), oldWorkOrderEntity.getDepartmentId(), oldWorkOrderEntity.getFlowStatus(), oldWorkOrderEntity.getData(), oldWorkOrderEntity.getCreatorId(),
                            oldWorkOrderEntity.getAddTime(), oldWorkOrderEntity.getUpdateTime(), oldWorkOrderEntity.getDel());
                }
                FormDataUtil.setSystemData(oldPaasFormData.getData(), oldPaasFormData);
                Data oldData = new Data(startNode.getAppId(), startNode.getMenuId(), startNode.getFormId(), oldPaasFormData.getId(),
                        oldPaasFormData.getData(), startNode.getBusinessType(), startNode.getSaasMark(), startNode.getId(), formDataUpdateDTO.getSubBusinessType());

                workflowRabbitmqDTO.getWorkflowTransferPOJO().setOldData(oldData);
                //发送mq
                workflowRabbitmqDTO.getWorkflowTransferPOJO().setBackupDataId(formDataSaveVO.getBackupDataId());
                workflowRabbitmqDTO.setOperatorId(formDataUpdateDTO.getUserId());
                startWorkflow(formDataUpdateDTO.getIsImport(), workflowRabbitmqDTO);

                // 判断工作流下一个节点是不是审批节点，是，修改同步返回提示
                WorkflowNodeEntity nextNode = workflowHelp.deliverToNextNode(workflowRabbitmqDTO.getWorkflowTransferPOJO(), startNode);
                if (Objects.equals(nextNode.getType(), WorkflowNodeTypeEnum.APPROVE_NODE.getType())) {
                    formDataSaveVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
                    formDataSaveVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                } else if (Objects.equals(nextNode.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())) {
                    WorkflowNodeEntity workflowNodeEntity = workflowHelp.deliverToNextNode(workflowRabbitmqDTO.getWorkflowTransferPOJO(), nextNode);
                    if (Objects.equals(workflowNodeEntity.getType(), WorkflowNodeTypeEnum.APPROVE_NODE.getType())) {
                        formDataSaveVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
                        formDataSaveVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                    }
                }

            }

        } catch (Exception e) {
            log.error("更新触发工作流失败", e);
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    
    }

    private void startWorkflow(Integer importFlag, WorkflowRabbitmqDTO workflowRabbitmqDTO) {
        if (Objects.equals(1, importFlag)) {
            // 导入需要走这个
            workflowProducer.startWorkflowNoApprove(workflowRabbitmqDTO);
        } else {
            workflowProducer.startWorkflow(workflowRabbitmqDTO);
        }
    }


    @Override
    public void workflowUpdateBatchTrigger(FormDataUpdateBatchDTO formDataUpdateBatchDTO, List<PaasFormDataEntityExt> oldDataList) throws XbbException {
        try {
            String corpid = formDataUpdateBatchDTO.getCorpid();
            Integer businessType = formDataUpdateBatchDTO.getBusinessType();
            businessType = workflowHelp.getSpecialBusinessType(businessType);
            List<WorkflowEntity> list = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid, formDataUpdateBatchDTO.getFormId(),
                    businessType, Arrays.asList(TriggerEventTypeEnum.ONLY_UPDATE.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
            if (CollectionUtils.isNotEmpty(list)) {
                // TODO 生效失效规则
                WorkflowEntity workflowEntity = list.get(0);
                WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), corpid, "startNode");
                PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formDataUpdateBatchDTO.getFormId(), businessType);
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainAndDataIdMap(paasFormExplainEntity.getExplains(), null);
                BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(startNode.getCorpid(), startNode.getFormId(), startNode.getBusinessType(), startNode.getSaasMark(), explainMap);
                FormTriggerNode formTriggerNode = JSON.parseObject(startNode.getConfigData(), FormTriggerNode.class);
                List<PaasFormDataEntityExt> paasFormDataEntityExts = formDataHelp.getByDataIdList(formDataUpdateBatchDTO.getDataIdList(), businessType, formDataUpdateBatchDTO.getSaasMark(), formDataUpdateBatchDTO.getFormId(), corpid);
                Map<Long, PaasFormDataEntityExt> oldDatMap = new HashMap<>(oldDataList.size());
                oldDataList.forEach(item->{
                    oldDatMap.put(item.getId(), item);
                });
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    boolean flag = validatePreCondition(formTriggerNode.getTriggerConditions(), paasFormDataEntityExt, businessRuleInfoPojo);
                    if (!flag) {
                        continue;
                    }
                    WorkflowTransferPOJO workflowTransferPOJO = WorkflowTransferHelp.createTransferData(paasFormDataEntityExt, null, null, null, corpid, formDataUpdateBatchDTO.getLoginUser(), startNode, WorkflowOperateEnum.UPDATE_BATCH.getType(), 0, startNode.getBusinessType());
                    PaasFormDataEntityExt oldPaasFormData = oldDatMap.get(paasFormDataEntityExt.getId());
                    FormDataUtil.setSystemData(oldPaasFormData.getData(), oldPaasFormData);
                    Data oldData = new Data(startNode.getAppId(), startNode.getMenuId(), startNode.getFormId(), oldPaasFormData.getId(), oldPaasFormData.getData(), startNode.getBusinessType(),
                            startNode.getSaasMark(), startNode.getId(), startNode.getBusinessType());
                    workflowTransferPOJO.setOldData(oldData);
                    //发mq
                    WorkflowRabbitmqDTO workflowRabbitmqDTO = new WorkflowRabbitmqDTO(workflowTransferPOJO, startNode, null);
                    workflowProducer.startWorkflowNoApprove(workflowRabbitmqDTO);
                }

            }

        } catch (Exception e) {
            log.error("批量编辑触发工作流失败", e);
        }
    }

    /**
     * 工作流删除触发
     * @param formDataDeleteBatchDTO
     * @return
     * @throws XbbException
     */
    @Override
    public void workflowDeleteTrigger(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<Long> deleteIds, WorkflowOperateEnum workflowOperateEnum) throws XbbException {
        try {
            String corpid = formDataDeleteBatchDTO.getCorpid();
            Integer businessType = formDataDeleteBatchDTO.getBusinessType();
            businessType = workflowHelp.getSpecialBusinessType(businessType);
            List<WorkflowEntity> list = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid, formDataDeleteBatchDTO.getFormId(), businessType, Collections.singletonList(TriggerEventTypeEnum.ONLY_DELETE.getType()));
            if (CollectionUtils.isNotEmpty(list)) {
                PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formDataDeleteBatchDTO.getFormId(), businessType);
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainAndDataIdMap(paasFormExplainEntity.getExplains(), null);
                WorkflowEntity workflowEntity = list.get(0);
                WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), corpid, "startNode");
                BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(startNode.getCorpid(), startNode.getFormId(), startNode.getBusinessType(), startNode.getSaasMark(), explainMap);
                FormTriggerNode formTriggerNode = JSON.parseObject(startNode.getConfigData(), FormTriggerNode.class);
                List<PaasFormDataEntityExt> paasFormDataEntityExts = formDataHelp.getByDataIdList(deleteIds, businessType, formDataDeleteBatchDTO.getSaasMark(), formDataDeleteBatchDTO.getFormId(), corpid);
                // 获取子表单数据
                Map<Long, JSONObject> formDataMap = paasFormSubDataModel.getSubDataMap(corpid, formDataDeleteBatchDTO.getSaasMark(), businessType, formDataDeleteBatchDTO.getFormId(), deleteIds, 1, PaasConstant.SUB_DATA_PAGE_NUM, DelEnum.DELETE_SUBFORM.getDel());

                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    boolean flag = validatePreCondition(formTriggerNode.getTriggerConditions(), paasFormDataEntityExt, businessRuleInfoPojo);
                    if (!flag) {
                        continue;
                    }
                    JSONObject jsonObject = formDataMap.get(paasFormDataEntityExt.getDataId()) == null ? new JSONObject() : formDataMap.get(paasFormDataEntityExt.getDataId());
                    paasFormDataEntityExt.getData().putAll(jsonObject);
                    WorkflowTransferPOJO workflowTransferPOJO = WorkflowTransferHelp.createTransferData(paasFormDataEntityExt, null, null, null,
                            corpid, formDataDeleteBatchDTO.getLoginUser(), startNode, workflowOperateEnum.getType(), 0, startNode.getBusinessType());
                    //发mq
                    WorkflowRabbitmqDTO workflowRabbitmqDTO = new WorkflowRabbitmqDTO(workflowTransferPOJO, startNode, null);
                    workflowProducer.startWorkflowNoApprove(workflowRabbitmqDTO);
                }

            }

        } catch (Exception e) {
            log.error("删除触发工作流失败", e);
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 是否启用新工作流
     * 且判断是否符合触发类型
     * @param formDataSaveDTO
     * @param beforeSaveVO
     * @param paasFormDataEntity
     * @return
     * @throws XbbException
     */
    @Override
    public boolean isEnableNewWorkflow(FormDataAddDTO formDataSaveDTO, BeforeSaveVO beforeSaveVO, PaasFormDataEntity paasFormDataEntity) throws XbbException {
        //未启用
        if (!commonHelp.isOpenWorkFlow(formDataSaveDTO.getCorpid())) {
            return false;
        }
        beforeSaveVO.setNoApprovalRequired(1);
        // 套餐限制
        Integer allStatus = packageStatusHelp.getPackageStatus(formDataSaveDTO.getCorpid(), ValueAddedTypeEnum.WORKFLOW, 1);
        if ( !Objects.equals(allStatus, PackageStatusEnum.NORMAL.getCode())) {
            formDataSaveDTO.setIsSatisfyTrigger(false);
            return true;
        }
        if (Objects.equals(1, formDataSaveDTO.getIsBusinessRule())) {
            // 禁止A触发B，B触发A这种循环触发工作流的逻辑
            formDataSaveDTO.setIsSatisfyTrigger(false);
            return true;
        }

        Integer businessType = formDataSaveDTO.getBusinessType();
        businessType = workflowHelp.getSpecialBusinessType(businessType);
        List<WorkflowEntity> list = workflowFormDataOperationService.getSatisfyTriggerEntitys(formDataSaveDTO.getCorpid(),
                formDataSaveDTO.getFormId(), businessType,
                Arrays.asList(TriggerEventTypeEnum.ONLY_ADD.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
        formDataSaveDTO.setIsSatisfyTrigger(false);
        //符合存在触发的类型
        if (CollectionUtils.isNotEmpty(list)) {
            formDataSaveDTO.setIsSatisfyTrigger(true);

            WorkflowEntity workflowEntity = list.get(0);
            // 如果触发的工作流有审批节点，那么先不管最后是否真的会走到审批节点，都先将主数据的审批状态改为待审批
            if (!Objects.equals(formDataSaveDTO.getIsImport(), 1) && Objects.equals(1, workflowEntity.getIsApprove())) {
                paasFormDataEntity.setFlowStatus(FlowStatusEnum.APPROVAL_PENDING.getType());
            }
            String corpid = formDataSaveDTO.getCorpid();
            WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), corpid, "startNode");
            BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(startNode.getCorpid(), startNode.getFormId(), startNode.getBusinessType(), startNode.getSaasMark(), beforeSaveVO.getExplainMap());
            FormTriggerNode formTriggerNode = JSON.parseObject(startNode.getConfigData(), FormTriggerNode.class);

            boolean flag = workflowFormDataOperationService.validatePreCondition(formTriggerNode.getTriggerConditions(), paasFormDataEntity, businessRuleInfoPojo);
            if (!flag) {
                formDataSaveDTO.setIsSatisfyTrigger(false);
            }
            //把查出来的置入formDataSaveDTO(这里职责很不分明, 后面触发要做的事,前面先查了)
            formDataSaveDTO.setWorkflowEntityList(list);
        }

        beforeSaveVO.setPaasFormDataEntity(paasFormDataEntity);
        return true;
    }


    /**
     * 是否启用工作流
     * 且判断是否符合触发类型
     * @param formDataUpdateDTO
     * @param paasFormDataEntity
     * @return
     * @throws XbbException
     */
    @Override
    public boolean isEnableNewWorkflow(FormDataUpdateDTO formDataUpdateDTO, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntity paasFormDataEntity, PaasFormDataEntity oldPaasFormData) throws XbbException {
        //未启用
        String corpid = formDataUpdateDTO.getCorpid();
        if (!commonHelp.isOpenWorkFlow(corpid)) {
            return false;
        }
        // 套餐限制
        Integer allStatus = packageStatusHelp.getPackageStatus(formDataUpdateDTO.getCorpid(), ValueAddedTypeEnum.WORKFLOW, 1);
        if ( !Objects.equals(allStatus, PackageStatusEnum.NORMAL.getCode())) {
            formDataUpdateDTO.setIsSatisfyTrigger(false);
            return true;
        }
        Integer businessType = formDataUpdateDTO.getBusinessType();
        Integer subBusinessType = formDataUpdateDTO.getSubBusinessType();
        Long formId = formDataUpdateDTO.getFormId();

        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        businessType = workflowHelp.getSpecialBusinessType(businessType);
        List<WorkflowEntity> list = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid,
                formDataUpdateDTO.getFormId(), businessType,
                Arrays.asList(TriggerEventTypeEnum.ONLY_UPDATE.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
        // 避免list为空导致空指针
        formDataUpdateDTO.setIsSatisfyTrigger(false);
        //符合存在触发的类型
        if (CollectionUtils.isNotEmpty(list)) {
            formDataUpdateDTO.setIsSatisfyTrigger(true);
            WorkflowEntity workflowEntity = list.get(0);
            if (Objects.equals(1, workflowEntity.getEnable())) {
                WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), corpid, "startNode");
                BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(startNode.getCorpid(), startNode.getFormId(), startNode.getBusinessType(), startNode.getSaasMark(), explainMap);
                FormTriggerNode formTriggerNode = JSON.parseObject(startNode.getConfigData(), FormTriggerNode.class);
                List<String> needApproveFields = formTriggerNode.getNeedApproveFields();

                //如果团队数据有改动，也算编辑过，也触发工作流（设置了对应的审批字段或者审批字段为空的时候，都要编辑进审批）
                TeamAfterVerifyDTO teamAfterVerifyDTO = formDataUpdateDTO.getSaasNeedRedundantAttrPoJo().getTeamAfterVerifyDTO();
                if(Objects.nonNull(teamAfterVerifyDTO)){
                    boolean ownerNeedApprove = CollectionUtils.isEmpty(needApproveFields) || needApproveFields.contains(FieldTypeEnum.OWNERID.getAlias());
                    boolean coUserNeedApprove = CollectionUtils.isEmpty(needApproveFields) || needApproveFields.contains(FieldTypeEnum.COUSERID.getAlias());
                    String dataId = formDataUpdateDTO.getDataId().toString();
                    //负责人编辑进审批
                    if(ownerNeedApprove &&
                            (CollectionUtils.isNotEmpty(teamAfterVerifyDTO.getAddMainUserMap().get(dataId))
                                    || CollectionUtils.isNotEmpty(teamAfterVerifyDTO.getDelMainUserMap().get(dataId)))){
                        formDataUpdateDTO.setTeamIsEdit(true);
                    }
                    //协同人编辑进审批
                    if(coUserNeedApprove &&
                            (CollectionUtils.isNotEmpty(teamAfterVerifyDTO.getAddCoUserMap().get(dataId))
                                    || CollectionUtils.isNotEmpty(teamAfterVerifyDTO.getDelCoUserMap().get(dataId)))){
                        formDataUpdateDTO.setTeamIsEdit(true);
                    }
                    //负责人或者协同人替换进审批
                    if((ownerNeedApprove || coUserNeedApprove) &&
                            (CollectionUtils.isNotEmpty(teamAfterVerifyDTO.getUpdateToMainUserMap().get(dataId))
                                    ||  CollectionUtils.isNotEmpty(teamAfterVerifyDTO.getUpdateToCoUserMap().get(dataId)))){
                        formDataUpdateDTO.setTeamIsEdit(true);
                    }
                }

                if (CollectionUtils.isNotEmpty(needApproveFields)) {
                    JSONObject newData = (JSONObject) paasFormDataEntity.getData().clone();
                    newData.put(FieldTypeEnum.DEPARTMENTID.getAlias(), paasFormDataEntity.getDepartmentId());
                    newData.put("serialNo", paasFormDataEntity.getSerialNo());
                    JSONObject oldData = (JSONObject) oldPaasFormData.getData().clone();
                    oldData.put("serialNo", oldPaasFormData.getSerialNo());
                    oldData.put(FieldTypeEnum.DEPARTMENTID.getAlias(), oldPaasFormData.getDepartmentId());
                    if (needApproveFields.contains(FieldTypeEnum.COUSERID.getAlias()) || needApproveFields.contains(FieldTypeEnum.OWNERID.getAlias())) {
                        if (UserTeamEnum.hasTeam(businessType)) {
                            Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            boolean isPublic = Objects.equals(XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode(), subBusinessType)
                                    || Objects.equals(XbbRefTypeEnum.CLUE_PUBLIC.getCode(), subBusinessType);
                            formDataFormExplainHelper.getUserIdMap(Collections.singletonList(oldPaasFormData.getId()), corpid, businessType,isPublic,mainUserMap,coUserMap);
                            List<String> mainUserList = mainUserMap.get(oldPaasFormData.getId());
                            List<String> coUserList = coUserMap.get(oldPaasFormData.getId());
                            oldData.put(FieldTypeEnum.OWNERID.getAlias(), mainUserList);
                            oldData.put(FieldTypeEnum.COUSERID.getAlias(), coUserList);
                        } else {
                            oldData.put(FieldTypeEnum.OWNERID.getAlias(), Arrays.asList(oldPaasFormData.getOwnerId()));
                            // 协同人
                            if (needApproveFields.contains(FieldTypeEnum.COUSERID.getAlias())) {
                                Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                                map.put("formId", formId);
                                map.put("appId", formDataUpdateDTO.getAppId());
                                map.put("formDataIdIn", Collections.singletonList(oldPaasFormData.getId()));
                                map.put("del", DelEnum.NORMAL.getDel());
                                List<PaasCoUserEntity> coUserList = paasCoUserModel.list(map);
                                if (!coUserList.isEmpty()) {
                                    List<String> coUserIdList = new ArrayList<>();
                                    coUserList.forEach(item-> coUserIdList.add(item.getCoUserId()));
                                    oldData.put(FieldTypeEnum.COUSERID.getAlias(), coUserIdList);
                                }
                            }
                        }
                    }

                    //下面是对目前放开的一些业务关联产品逻辑进行处理,提前对把oldData中的关联产品数据封装成跟新增关联产品的数据一致
                    packageOldProductInfo(corpid, businessType, oldData, formDataUpdateDTO.getDataId());

                    boolean needApprove = CompareUtil.isNeedApprove(newData, oldData, needApproveFields);
                    if (!needApprove) {
                        formDataUpdateDTO.setIsSatisfyTrigger(false);
                        return true;
                    }
                }
                // 判断
                boolean flag = workflowFormDataOperationService.validatePreCondition(formTriggerNode.getTriggerConditions(), paasFormDataEntity, businessRuleInfoPojo);
                if (!flag) {
                    formDataUpdateDTO.setIsSatisfyTrigger(false);
                    return true;
                }
            }
            // 如果触发的工作流有审批节点，那么先不管最后是否真的会走到审批节点，都先将主数据的审批状态改为待审批
            if (!Objects.equals(formDataUpdateDTO.getIsImport(), 1) && Objects.equals(1, workflowEntity.getIsApprove())) {
                paasFormDataEntity.setFlowStatus(FlowStatusEnum.APPROVAL_PENDING.getType());
            }
            //把查出来的置入formDataSaveDTO(这里职责很不分明, 后面触发要做的事,前面先查了)
            formDataUpdateDTO.setWorkflowEntityList(list);
        }
        return true;

    }

    /**
     * 封装老数据的关联产品信息
     *
     * @param corpid 公司id
     * @param businessType 业务类型
     * @param oldData 老数据
     * @param dataId 主数据id
     */
    private void packageOldProductInfo(String corpid, Integer businessType, JSONObject oldData, Long dataId) throws XbbException {
        //需要处理的业务类型
        List<Integer> shouldHandleBusinessList = Arrays.asList(XbbRefTypeEnum.QUOTATION.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(),
                XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.REFUND.getCode());
        if (!shouldHandleBusinessList.contains(businessType)) {
            return;
        }
        SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
        saasAnalysisDataDTO.setBusinessType(businessType);
        saasAnalysisDataDTO.setDataId(dataId);
        saasAnalysisDataDTO.setCorpid(corpid);
        formatProductHelp.formatProduct(saasAnalysisDataDTO, oldData, null, false);
    }

    /**
     * 校验触发条件是否匹配
     * @param preConditionList
     * @param thisFormData
     * @param businessRuleInfoPojo
     * @return false : 不可执行当前这条工作流； true：可以执行
     * @throws XbbException
     */
    @Override
    public boolean validatePreCondition(List<FilterConditionsPoJo> preConditionList, PaasFormDataEntity thisFormData, BusinessRuleInfoPojo businessRuleInfoPojo) throws XbbException {
        if (CollectionsUtil.isEmpty(preConditionList)) {
            return true;
        }
        try {
            Map<String, FieldAttrEntity> thisExplainMap = businessRuleInfoPojo.getThisExplainMap();
            for (FilterConditionsPoJo item : preConditionList) {
                FieldAttrEntity fieldAttrEntity = thisExplainMap.get(item.getAttr());
                if (Objects.isNull(fieldAttrEntity)) {
                    break;
                }
                // 获取固定值的数据
                FieldAnalyseService fieldAnalyseService = fieldAnalyseMap.get(fieldAttrEntity.getFieldType());
                Object object = fieldAnalyseService.handlerPreConditionValue(fieldAttrEntity, businessRuleInfoPojo, item);
                boolean result = SymbolHelp.handleSymbol(object, thisFormData, item, fieldAttrEntity);
                if (!result) {
                    return false;
                }
            }
        } catch (Exception e) {
            log.error("businessRuleConditionHelp.validatePreCondition 出错：" , e);
            return false;
        }
        return true;
    }

    @Override
    public boolean isApprovedEdit(Long formId, String corpid, Integer saasMark, Integer businessType, Integer flowStatus, UserVO userVO) {
        Integer allowEditAfterFinished = 0;
        String alias = RedisPrefixConstant.ALLOW_EDIT_AFTER_FINISHED;
        FormConfigEntity formConfigEntity = formConfigModel.getByConfig(alias, corpid, formId, saasMark, businessType);
        if (Objects.nonNull(formConfigEntity)) {
            allowEditAfterFinished = Integer.valueOf(formConfigEntity.getConfigValue());
        }
        boolean isEdit = Objects.equals(1, allowEditAfterFinished) || userVO.isAdminOrBoss();
        if (!isEdit) {
            isEdit = !FlowStatusEnum.PASS.getType().equals(flowStatus);
        }
        return isEdit;
    }

    @Override
    public void isApprovedEdit(boolean fromCopy, Long appId, Long menuId, Long formId, String corpid, Integer saasMark, Integer businessType, Integer flowStatus, UserVO userVO) throws XbbException {
        if (!fromCopy) {
            // 来自复制的不判断该逻辑
            // 是否可以编辑
            boolean isEdit;
            boolean isOpenWorkflow = commonHelp.isOpenWorkFlow(corpid);
            if (isOpenWorkflow) {
                isEdit = isApprovedEdit(formId, corpid,saasMark, businessType, flowStatus, userVO);
            } else {
                isEdit = paasProcessTemplateModel.isApprovedEdit(appId, menuId, formId, userVO, flowStatus);
            }
            if ( !isEdit ) {
                throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200017);
            }
        }
    }


    /**
     * 是否启用新工作流
     * 且判断是否符合触发类型
     * @param formDataDeleteBatchDTO
     * @param formDataDeleteBatchVO
     * @return
     * @throws XbbException
     */
    @Override
    public boolean isEnableNewWorkflow(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<Long> deleteIds, WorkflowOperateEnum workflowOperateEnum) throws XbbException {
        if (!commonHelp.isOpenWorkFlow(formDataDeleteBatchDTO.getCorpid())) {
            return false;
        }
        if (CollectionUtils.isEmpty(deleteIds)) {
            return true;
        }
        // 套餐限制
        Integer allStatus = packageStatusHelp.getPackageStatus(formDataDeleteBatchDTO.getCorpid(), ValueAddedTypeEnum.WORKFLOW, deleteIds.size());
        if ( !Objects.equals(allStatus, PackageStatusEnum.NORMAL.getCode())) {
            return true;
        }
        if (Objects.nonNull(formDataDeleteBatchDTO.getIsBusinessRule()) && !Objects.equals(0, formDataDeleteBatchDTO.getIsBusinessRule())) {
            // 禁止A触发B，B触发A这种循环触发工作流的逻辑
            return true;
        }
        //是不是要循环发送
        workflowFormDataOperationService.workflowDeleteTrigger(formDataDeleteBatchDTO, deleteIds, workflowOperateEnum);
        return true;
    }

    @Override
    public void executeWorkflow(PaasFormDataEntity paasFormDataEntity, Map<String, FieldAttrEntity> explainMap, UserVO userVO, Integer subBusinessType, Long workflowId, String corpid) throws XbbException {
        WorkflowEntity workflowEntity = workflowModel.getByKey(workflowId, corpid);
        if (Objects.isNull(workflowEntity) || Objects.equals(0, workflowEntity.getEnable())) {
            return;
        }
        WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), corpid, "startNode");

        SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
        setSaasNeedPojo(saasNeedRedundantAttrPojo);
        //构建mq消息
        WorkflowRabbitmqDTO workflowRabbitmqDTO = buildMqMessage(startNode, corpid, paasFormDataEntity, userVO, explainMap, saasNeedRedundantAttrPojo, WorkflowOperateEnum.CUSTOM_EXECUTE.getType(), 0, subBusinessType);
        // 发送mq
        startWorkflow(0, workflowRabbitmqDTO);

    }

    /**
     * 精简一下pojo
     * @param saasNeedRedundantAttrPojo
     */
    private void setSaasNeedPojo(SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) {
        if (Objects.nonNull(saasNeedRedundantAttrPojo.getNeedAddValidateDataDTO())) {
            saasNeedRedundantAttrPojo.getNeedAddValidateDataDTO().forEach(this::setBaseDTO2Null);
        }
        if (Objects.nonNull(saasNeedRedundantAttrPojo.getNeedDelValidateDataDTO())) {
            saasNeedRedundantAttrPojo.getNeedDelValidateDataDTO().forEach(this::setBaseDTO2Null);
        }
        if (Objects.nonNull(saasNeedRedundantAttrPojo.getNeedUpdateValidateDataDTO())) {
            saasNeedRedundantAttrPojo.getNeedUpdateValidateDataDTO().forEach(this::setBaseDTO2Null);
        }
        if (Objects.nonNull(saasNeedRedundantAttrPojo.getAddBatchDTO())) {
            setBaseDTO2Null(saasNeedRedundantAttrPojo.getAddBatchDTO());
        }
        if (Objects.nonNull(saasNeedRedundantAttrPojo.getAddPaymentSheetBatchDTO())) {
            setBaseDTO2Null(saasNeedRedundantAttrPojo.getAddPaymentSheetBatchDTO());
        }
        if (Objects.nonNull(saasNeedRedundantAttrPojo.getAddWriteOffPrepaymentBatchDTO())) {
            setBaseDTO2Null(saasNeedRedundantAttrPojo.getAddWriteOffPrepaymentBatchDTO());
        }
        if (Objects.nonNull(saasNeedRedundantAttrPojo.getBeforeSaveMyTeamDTO())) {
            setBaseDTO2Null(saasNeedRedundantAttrPojo.getBeforeSaveMyTeamDTO());
        }
    }

    private void setBaseDTO2Null (BaseDTO baseDTO) {
        baseDTO.setBrowserInfo(null);
        baseDTO.setHttpHeader(null);
        baseDTO.setIp(null);
        baseDTO.setLocale(null);
        baseDTO.setLoginUser(null);
        baseDTO.setPlatform(null);
    }

}
